<template>
  <div class="login">
    <div class="login-container">
      <div class="title">用户登录</div>
      <!-- 用户登录表单 -->
      <el-form
        :model="user"
        label-width="80px"
        style="max-width: 400px"
        :rules="rules"
        ref="loginFormRef"
        @submit="handleLogin"
      >
        <el-form-item label="用户名" prop="username">
          <el-input v-model="user.username" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input
            v-model="user.password"
            type="password"
            placeholder="请输入密码"
            show-password
          />
        </el-form-item>
        <el-form-item>
          <el-checkbox v-model="user.remember" name="type">
            记住用户名与密码
          </el-checkbox>
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
            native-type="submit"
            class="login-btn"
          >登录</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, type FormRules } from 'element-plus'
import CryptoJS from 'crypto-js'
import useUserStore from '@/store/user'

const router = useRouter()
const userStore = useUserStore()

// 加密钥使用到的密钥
const secret = 'akldjf193487ujlkadf.a,dfqoijasdf'

// 登录使用到的用户账号信息
const user = ref<ILoginAccount>({
  username: '',
  password: '',
  remember: false,
})

// 初始加载时，如果本地有保存记住的用户账号信息，则读取出该账号信息
// 还原显示到表单中。由于保存的账号会经加密处理，所以在原来时需要对应解密
const load = () => {
  // 读取本地保存的账号信息
  const account = localStorage.getItem('account')
  if (account) {
    // 有账号信息，则解密处理
    const origin = CryptoJS.AES.decrypt(account, secret).toString(CryptoJS.enc.Utf8)
    // console.log('解密后的数据：', origin)
    // 使用=号将明文数据进行分割处理
    const [username, password] = origin.split('=')
    // 设置到 user 对象中
    user.value = {
      username,
      password,
      remember: true,
    }
  }
}
load()

// 表单字段校验规则
interface IAccountRules {
  username: string
  password: string
}
const rules = ref<FormRules<IAccountRules>>({
  username: [
    { required: true, message: '用户名必填!', trigger: 'blur' },
  ],
  password: [
    { required: true, message: '密码必填!', trigger: 'blur' },
    { min: 5, max: 20, message: '密码长度在6到20位之间!', trigger: 'blur' },
  ],
})

// 引用登录表单的组件实例
const loginFormRef = ref<any>()
// 处理登录
const handleLogin = async (event: any) => {
  // 阻止表单提交的默认行为
  event.preventDefault()
  try {
    // 调用表单组件实例提供(暴露出来)的方法，进行表单校验
    // 在表单校验通过后，才能够发送网络请求进行用户验证
    const result = await loginFormRef.value.validate()
   
    if (result) { // 表单校验通过
      // 调用 store 中提供的登录 action 方法，
      // 将登录成功后的用户数据保存到 store 中
      const {success, message} = await userStore.loginAction(user.value)
      if (success) {
        // 登录成功后跳转到主页面
        // 但通常在跳转前，还需要判断是否有勾选记住用户名与密码
        // 如果有勾选记住用户名与密码，则将用户名与密码数据保存到本地
        // 如果未勾选，则将本地已保存的用户名与密码进行移除处理
        if (user.value.remember) { // 记住
          const account = user.value.username + '=' + user.value.password
          // 将待保存到本地的用户账号数据进行加密处理
          const pass = CryptoJS.AES.encrypt(account, secret).toString();
          // 将加密后的数据保存到本地
          localStorage.setItem('account', pass)
        } else { // 不记住
          localStorage.removeItem('account')
        }
        // 跳转到主页面
        router.push('/dashboard')
      } else {
        ElMessage({
          message,
          type: 'error',
        })
      }
    }
  } catch (error) {
    console.log('表单提交异常:', error)
  }
}
</script>

<style lang="scss" scoped>
.login {
  display: flex;
  height: 100vh;

  &-container {
    width: 400px;
    height: fit-content;
    padding: 24px;
    margin: auto;
    // border: 1px solid #000;
  }

  .title {
    text-align: center;
    font-size: 18px;
    font-weight: 700;
    line-height: 3;
  }

  &-btn {
    display: block;
    width: 100%;
  }
}
</style>
